package ru.spbu.math.android.cbrf.dataprovider.cbrf;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.content.res.Resources;
import android.util.Log;

import ru.spbu.math.android.cbrf.R;
import ru.spbu.math.android.cbrf.model.Category;
import ru.spbu.math.android.cbrf.model.RateType;

/**
 * Class for keeping data about all available RateTypes for CbrfProvider
 *
 */
class RateTypeStore {

	private final String LOG_TAG = "Cbrf.RateTypeStore";
	
	private static RateTypeStore instance;

	private Map<String, RateType> rateTypes;
	private ArrayList<RateType> currencyList;
	private ArrayList<RateType> metalList;
	
	private static String currencyCategory;
	private static String metalCategory;

	public static RateTypeStore getInstance(Resources resources) {
		if (instance == null) {
			instance = new RateTypeStore(resources);
		}
		return instance;
	}

	private RateTypeStore(Resources resources) {

		rateTypes = new HashMap<String, RateType>();
		currencyList = new ArrayList<RateType>();
		metalList = new ArrayList<RateType>();
		
		currencyCategory = resources.getString(R.string.Cbrf_Currency);
		metalCategory = resources.getString(R.string.Cbrf_Metal);
         
		try {
			RateTypeSaxHandler handler = new RateTypeSaxHandler();
			handler.setResources(resources);
	        SAXParserFactory factory = SAXParserFactory.newInstance();
	        SAXParser parser = factory.newSAXParser();
	        InputSource courseXml = new InputSource(resources.openRawResource(R.raw.rate_type_cbrf));
			parser.parse(courseXml, handler);
			currencyList = (ArrayList<RateType>) handler.getCurrency();
			metalList = (ArrayList<RateType>) handler.getMetal();
			
			Log.d(LOG_TAG, "was parsed");
			Log.d(LOG_TAG, "currencyList size: " + currencyList.size());
			Log.d(LOG_TAG, "metalList size: " + metalList.size());
			for(RateType rateType : currencyList){
				Log.d(LOG_TAG, "Currency. id: " + rateType.getId());
				rateTypes.put(rateType.getId(), rateType);
			}
			
			for(RateType rateType : metalList){
				Log.d(LOG_TAG, "Metal. id: " + rateType.getId());
				rateTypes.put(rateType.getId(), rateType);
			}
			
		} catch (ParserConfigurationException e) {
			Log.e(LOG_TAG, "ParserConfigurationException");
		} catch (SAXException e) {
			Log.e(LOG_TAG, "SAXException");
		} catch (IOException e) {
			Log.e(LOG_TAG, "IOException");
		}
	}
	
	/**
	 * @return all available categories
	 */
	public List<Category> getCategories() {
		ArrayList<Category> categories = new ArrayList<Category>();
		categories.add(new Category(currencyCategory));
		categories.add(new Category(metalCategory));
		return categories;
	}
	
	@SuppressWarnings("unchecked")
	public List<RateType> getRateTypesByCategory(Category category) {
		
		// TODO change it!!
		if (category.getName().equals(currencyCategory)) {
			return (List<RateType>) currencyList.clone();
		} else if (category.getName().equals(metalCategory)) {
			return (List<RateType>) metalList.clone();
		}
		
		return null;
	}
	
	/**
	 * @param id
	 * @return RateType
	 */
	public RateType getRateType(String id) {
		return rateTypes.get(id);
	}
	
	/**
	 * Checks is rate with specified id metal or not
	 * @param id
	 * @return
	 */
	public boolean isMetal(String id) {
		return metalList.contains(rateTypes.get(id));
	}
}
